package cn.ctodb.eadp.uaa.domain;

import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.springframework.data.elasticsearch.annotations.Document;

import javax.persistence.*;
import javax.validation.constraints.*;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import java.util.Objects;

/**
 * Entity Dept
 */
@ApiModel(description = "Entity Dept")
@Entity
@Table(name = "dept")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Document(indexName = "dept")
public class Dept implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull
    @Column(name = "code", nullable = false)
    private String code;

    @NotNull
    @Column(name = "name", nullable = false)
    private String name;

    @Column(name = "short_name")
    private String shortName;

    @Column(name = "description")
    private String description;

    @OneToMany(mappedBy = "parent")
    @JsonIgnore
    @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
    private Set<Dept> children = new HashSet<>();

    @ManyToOne
    private UserInfo manager;

    @ManyToMany
    @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
    @JoinTable(name = "dept_user_info",
               joinColumns = @JoinColumn(name="depts_id", referencedColumnName="id"),
               inverseJoinColumns = @JoinColumn(name="user_infos_id", referencedColumnName="id"))
    private Set<UserInfo> userInfos = new HashSet<>();

    @ManyToOne
    private Dept parent;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getCode() {
        return code;
    }

    public Dept code(String code) {
        this.code = code;
        return this;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public Dept name(String name) {
        this.name = name;
        return this;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getShortName() {
        return shortName;
    }

    public Dept shortName(String shortName) {
        this.shortName = shortName;
        return this;
    }

    public void setShortName(String shortName) {
        this.shortName = shortName;
    }

    public String getDescription() {
        return description;
    }

    public Dept description(String description) {
        this.description = description;
        return this;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Set<Dept> getChildren() {
        return children;
    }

    public Dept children(Set<Dept> depts) {
        this.children = depts;
        return this;
    }

    public Dept addChild(Dept dept) {
        this.children.add(dept);
        dept.setParent(this);
        return this;
    }

    public Dept removeChild(Dept dept) {
        this.children.remove(dept);
        dept.setParent(null);
        return this;
    }

    public void setChildren(Set<Dept> depts) {
        this.children = depts;
    }

    public UserInfo getManager() {
        return manager;
    }

    public Dept manager(UserInfo userInfo) {
        this.manager = userInfo;
        return this;
    }

    public void setManager(UserInfo userInfo) {
        this.manager = userInfo;
    }

    public Set<UserInfo> getUserInfos() {
        return userInfos;
    }

    public Dept userInfos(Set<UserInfo> userInfos) {
        this.userInfos = userInfos;
        return this;
    }

    public Dept addUserInfo(UserInfo userInfo) {
        this.userInfos.add(userInfo);
        userInfo.getDepts().add(this);
        return this;
    }

    public Dept removeUserInfo(UserInfo userInfo) {
        this.userInfos.remove(userInfo);
        userInfo.getDepts().remove(this);
        return this;
    }

    public void setUserInfos(Set<UserInfo> userInfos) {
        this.userInfos = userInfos;
    }

    public Dept getParent() {
        return parent;
    }

    public Dept parent(Dept dept) {
        this.parent = dept;
        return this;
    }

    public void setParent(Dept dept) {
        this.parent = dept;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        Dept dept = (Dept) o;
        if (dept.id == null || id == null) {
            return false;
        }
        return Objects.equals(id, dept.id);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(id);
    }

    @Override
    public String toString() {
        return "Dept{" +
            "id=" + id +
            ", code='" + code + "'" +
            ", name='" + name + "'" +
            ", shortName='" + shortName + "'" +
            ", description='" + description + "'" +
            '}';
    }
}
